package com.cupcorn.lib;

import java.util.Random;

import org.andengine.entity.Entity;
import org.andengine.entity.modifier.MoveYModifier;
import org.andengine.entity.shape.RectangularShape;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.util.Log;

import com.cupcorn.lib.define.GameEngineConfiguration;
import com.cupcorn.lib.define.iDefines;
import com.cupcorn.lib.game.GameEngine;
import com.cupcorn.lib.game.GameSprite;

public class Utils
{
	public static int getPosX(float x, float width, Anchor anchor, Ratio ratio, RectangularShape rectShape)
	{
		return (int) (getAnchorX(width, anchor, rectShape) + getRatioWidth(x, ratio));
	}
	
	public static int getPosX(float x, float width, Anchor anchor, Ratio ratio)
	{
		return (int) (getAnchorX(width, anchor) + getRatioWidth(x, ratio));
	}
	
	public static int getPosY(float y, float height, Anchor anchor, Ratio ratio, RectangularShape rectShape)
	{
		return (int) (getAnchorY(height, anchor, rectShape) + getRatioHeight(y, ratio));
	}
	
	public static int getPosY(float y, float height, Anchor anchor, Ratio ratio)
	{
		return (int) (getAnchorY(height, anchor) + getRatioHeight(y, ratio));
	}
	
	public static float getRatioWidth(float value)
	{
		return getRatioWidth(value, Ratio.WIDTH);
	}
	
	public static float getRatioWidth(float value, Ratio ratio)
	{
		float nil = 0;
		switch (ratio)
		{
			case NONE:
				nil = value;
				break;
			
			case HEIGHT:
				nil = (value / iDefines.MASTER_HEIGHT) * GameEngine.CAMERA_HEIGHT;
				break;
			
			default:
				nil = (value / iDefines.MASTER_WIDTH) * GameEngine.CAMERA_WIDTH;
				break;
		}
		return nil;
	}
	
	public static float getRatioHeight(float value)
	{
		return getRatioHeight(value, Ratio.HEIGHT);
	}
	
	public static float getRatioHeight(float value, Ratio ratio)
	{
		float nil = 0;
		switch (ratio)
		{
			case NONE:
				nil = value;
				break;
			
			case WIDTH:
				nil = (value / iDefines.MASTER_WIDTH) * GameEngine.CAMERA_WIDTH;
				break;
			
			default:
				nil = (value / iDefines.MASTER_HEIGHT) * GameEngine.CAMERA_HEIGHT;
				break;
		}
		return nil;
	}
	
	public static void TRACE(String somethingToTrace)
	{
		if (!GameEngineConfiguration.enable_trace) { return; }
		
		Log.d(GameEngineConfiguration.trace_tag, somethingToTrace);
	}
	
	public static void TRACE(Object somethingToTrace)
	{
		if (!GameEngineConfiguration.enable_trace) { return; }
		
		Log.d(GameEngineConfiguration.trace_tag, String.valueOf(somethingToTrace));
	}
	
	public static int getAnchorX(float width, Anchor anchor)
	{
		return getAnchorX(width, anchor, null);
	}
	
	public static int getAnchorY(float height, Anchor anchor)
	{
		return getAnchorY(height, anchor, null);
	}
	
	public static int getAnchorY(float height, Anchor anchor, RectangularShape rectShape)
	{
		float h = GameEngine.CAMERA_HEIGHT;
		if (rectShape != null)
		{
			h = rectShape.getHeight();
		}
		
		float y;
		switch (anchor)
		{
			case CENTER:
			{
				y = (h / 2) - (height / 2);
			}
				break;
			case CENTER_LEFT:
			{
				y = (h / 2) - (height / 2);
			}
				break;
			case CENTER_RIGHT:
			{
				y = (h / 2) - (height / 2);
			}
				break;
			case BOTTOM_CENTER:
			{
				y = h - height;
			}
				break;
			case BOTTOM_LEFT:
			{
				y = h - height;
			}
				break;
			case BOTTOM_RIGHT:
			{
				y = h - height;
			}
				break;
			default:
			{
				y = 0.0f;
			}
		}
		return (int) y;
	}
	
	public static int getAnchorX(float width, Anchor anchor, RectangularShape rectShape)
	{
		float w = GameEngine.CAMERA_WIDTH;
		if (rectShape != null)
		{
			w = rectShape.getWidth();
		}
		float x;
		switch (anchor)
		{
			case TOP_CENTER:
			{
				x = (w / 2) - (width / 2);
			}
				break;
			case TOP_RIGHT:
			{
				x = w - width;
			}
				break;
			case CENTER:
			{
				x = (w / 2) - (width / 2);
			}
				break;
			case CENTER_RIGHT:
			{
				x = w - width;
			}
				break;
			case BOTTOM_CENTER:
			{
				x = (w / 2) - (width / 2);
			}
				break;
			case BOTTOM_RIGHT:
			{
				x = w - width;
			}
				break;
			default:
			{
				x = 0.0f;
			}
		}
		return (int) x;
	}
	
	public static int GetRandomInRange(int begin, int end)
	{
		if (begin > end)
		{
			System.out.println("end number shouldn't bigger that the beginning number");
			return -1;
		}
		Random randomGenerator = new Random();
		int range = end - begin;
		return begin + (randomGenerator.nextInt(range + 1));
	}
	
	public static int GetRandomBetweenTwo(int first, int second)
	{
		Random random = new Random();
		boolean firstIndex = random.nextBoolean();
		if (firstIndex) { return first; }
		return second;
	}
	
	public static int GetRandomFromArray(int[] array)
	{
		Random random = new Random();
		int index = 0;
		try
		{
			index = random.nextInt(array.length);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return array[index];
	}
	
	public static String limit(String value, int length)
	{
		StringBuilder buf = new StringBuilder(value);
		if (buf.length() > length)
		{
			buf.setLength(length);
			buf.append("...");
		}
		
		return buf.toString();
	}
	
	public static float getCenter(float value1, float value2)
	{
		return (value1 - value2) / 2;
	}
	
	public static boolean IsTouched_Move(Sprite sprite, TouchEvent pSceneTouchEvent)
	{
		if (((pSceneTouchEvent.getX() > sprite.getX() && pSceneTouchEvent.getX() < sprite.getX() + sprite.getWidth()) && (pSceneTouchEvent.getY() > sprite
			.getY() && pSceneTouchEvent.getY() < sprite.getY() + sprite.getHeight())) && pSceneTouchEvent.getAction() == TouchEvent.ACTION_MOVE) { return true; }
		return false;
	}
	
	public static boolean IsTouched_Down(Sprite sprite, TouchEvent pSceneTouchEvent)
	{
		if (((pSceneTouchEvent.getX() > sprite.getX() && pSceneTouchEvent.getX() < sprite.getX() + sprite.getWidth()) && (pSceneTouchEvent.getY() > sprite
			.getY() && pSceneTouchEvent.getY() < sprite.getY() + sprite.getHeight())) && pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN) { return true; }
		return false;
	}
	
	public static boolean IsTouched_Up(Sprite sprite, TouchEvent pSceneTouchEvent)
	{
		if (((pSceneTouchEvent.getX() > sprite.getX() && pSceneTouchEvent.getX() < sprite.getX() + sprite.getWidth()) && (pSceneTouchEvent.getY() > sprite
			.getY() && pSceneTouchEvent.getY() < sprite.getY() + sprite.getHeight())) && pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) { return true; }
		return false;
	}
	
	public static boolean isOnArea(float sceneX, float sceneY, GameSprite sprite)
	{
		boolean bol = false;
		
		if (sceneX > sprite.getX() && sceneX < sprite.getX() + sprite.getWidth() && sceneY > sprite.getY() && sceneY < sprite.getY() + sprite.getHeight())
			bol = true;
		
		return bol;
	}
	
	public static float getXAnchor(RectangularShape child, float widthParent, Anchor anchor)
	{
		switch (anchor)
		{
			case TOP_LEFT:
			case CENTER_LEFT:
			case BOTTOM_LEFT:
			{
				return 0;
			}
			case TOP_CENTER:
			case CENTER:
			case BOTTOM_CENTER:
			{
				return widthParent / 2 - child.getWidth() / 2;
			}
			case TOP_RIGHT:
			case CENTER_RIGHT:
			case BOTTOM_RIGHT:
			{
				return widthParent - child.getWidth();
			}
		}
		
		return 0;
	}
	
	public static float getXAnchor(RectangularShape child, Anchor anchor)
	{
		switch (anchor)
		{
			case TOP_LEFT:
			case CENTER_LEFT:
			case BOTTOM_LEFT:
			{
				return 0;
			}
			case TOP_CENTER:
			case CENTER:
			case BOTTOM_CENTER:
			{
				return ((RectangularShape) child.getParent()).getWidth() / 2 - child.getWidth() / 2;
			}
			case TOP_RIGHT:
			case CENTER_RIGHT:
			case BOTTOM_RIGHT:
			{
				return ((RectangularShape) child.getParent()).getWidth() - child.getWidth();
			}
		}
		
		return 0;
	}
	
	public static float getYAnchor(RectangularShape child, float heightParent, Anchor anchor)
	{
		switch (anchor)
		{
			case TOP_LEFT:
			case TOP_CENTER:
			case TOP_RIGHT:
			{
				return 0;
			}
			case CENTER_LEFT:
			case CENTER:
			case CENTER_RIGHT:
			{
				return heightParent / 2 - child.getHeight() / 2;
			}
			case BOTTOM_LEFT:
			case BOTTOM_CENTER:
			case BOTTOM_RIGHT:
			{
				return heightParent - child.getHeight();
			}
		}
		
		return 0;
	}
	
	public static float getYAnchor(RectangularShape child, Anchor anchor)
	{
		switch (anchor)
		{
			case TOP_LEFT:
			case TOP_CENTER:
			case TOP_RIGHT:
			{
				return 0;
			}
			case CENTER_LEFT:
			case CENTER:
			case CENTER_RIGHT:
			{
				return ((RectangularShape) child.getParent()).getHeight() / 2 - child.getHeight() / 2;
			}
			case BOTTOM_LEFT:
			case BOTTOM_CENTER:
			case BOTTOM_RIGHT:
			{
				return ((RectangularShape) child.getParent()).getHeight() - child.getHeight() / 2;
			}
		}
		
		return 0;
	}
	
	public static void registerMoveYModifier(Entity entity, float duration, float far)
	{
		entity.registerEntityModifier(new MoveYModifier(duration, entity.getY() - far, entity.getY()));
	}
	
	public static String getUsername()
	{
		AccountManager manager = (AccountManager) GameEngine.instance().getSystemService(GameEngine.ACCOUNT_SERVICE);
		Account[] list = manager.getAccounts();
		String gmail = null;
		
		for (Account account : list)
		{
			if (account.type.equalsIgnoreCase("com.google"))
			{
				gmail = account.name;
				return gmail.split("@")[0];
			}
		}
		
		return "unidentified";
	}
	
	public static boolean isOnScreen(GameEngine engine, RectangularShape rectangularShape)
	{
		if (rectangularShape.getX() + rectangularShape.getWidth() > engine.camera.getXMin() && rectangularShape.getX() < engine.camera.getXMax() &&
			rectangularShape.getY() + rectangularShape.getHeight() > engine.camera.getYMin() && rectangularShape.getY() < engine.camera.getYMax())
			return true;
		else
			return false;
	}
}
